import copy
import warnings
from collections import OrderedDict, UserDict, UserList, abc

# 用于装饰器函数，帮助保留被装饰函数的元数据（如名称、文档字符串）。
from functools import wraps

# chain: 用于将多个迭代器连接成一个连续的迭代器。
# repeat: 用于重复一个对象指定次数，或无限次。
from itertools import chain, repeat

# AsyncGenerator: 异步生成器类型。
# Callable: 表示可调用对象（如函数）。
from typing import Any, AsyncGenerator, Callable, Dict, Generator, Iterable, List, Mapping, Optional, Tuple, Union

from lagent.agents.aggregator import DefaultAggregator
from lagent.hooks import Hook, RemovableHandle
from lagent.llms import BaseLLM
from lagent.memory import Memory, MemoryManager
from lagent.prompts.parsers import StrParser
from lagent.prompts.prompt_template import PromptTemplate
from lagent.schema import AgentMessage, ModelStatusCode
from lagent.utils import create_object


class Agent:
    """
    基础代理类
    
    @description 实现了与LLM模型交互、消息处理和状态管理的核心功能
    """

    def __init__(
        self,
        llm: Union[BaseLLM, Dict] = None,
        template: Union[PromptTemplate, str, dict, List[dict]] = None,
        memory: Dict = dict(type=Memory),
        output_format: Optional[Dict] = None,
        aggregator: Dict = dict(type=DefaultAggregator),
        name: Optional[str] = None,
        description: Optional[str] = None,
        hooks: Optional[Union[List[Dict], Dict]] = None,
    ):
        """
        初始化Agent实例     
        
        参数:
            llm: LLM模型配置或实例
            template: 提示模板
            memory: 记忆配置
            output_format: 输出格式化器配置
            aggregator: 消息聚合器配置
            name: 代理名称
            description: 代理描述
            hooks: 钩子函数配置
        """
        # 设置代理名称，如果未提供则使用类名
        self.name = name or self.__class__.__name__
        
        # 初始化LLM模型实例
        self.llm: BaseLLM = create_object(llm)
        
        # 初始化记忆管理器
        self.memory: MemoryManager = MemoryManager(memory) if memory else None
        
        # 初始化输出格式化器
        self.output_format: StrParser = create_object(output_format)
        
        # 设置提示模板
        self.template = template
        
        # 设置代理描述
        self.description = description
        
        # 初始化消息聚合器
        self.aggregator: DefaultAggregator = create_object(aggregator)
        
        # 初始化钩子函数字典
        self._hooks: Dict[int, Hook] = OrderedDict()
        
        # 注册钩子函数
        if hooks:
            for hook in hooks:
                # 创建钩子函数实例并注册
                hook = create_object(hook)
                self.register_hook(hook)

    def update_memory(self, message, session_id=0):
        if self.memory:
            self.memory.add(message, session_id=session_id)

    def __call__(self, *message: AgentMessage, session_id=0, **kwargs) -> AgentMessage:
        """
        处理输入消息并生成响应
        
        参数:
            message: 输入消息
            session_id: 会话ID
            
        返回:
            AgentMessage: 处理后的响应消息
        """
        # 1. 标准化消息格式
        message = [AgentMessage(sender='user', content=m) if isinstance(m, str) else copy.deepcopy(m) for m in message]
        
        # 2. 执行前置钩子
        for hook in self._hooks.values():
            result = hook.before_agent(self, message, session_id)
            if result:
                message = result
                
        # 3.更新记忆并处理消息
        self.update_memory(message, session_id=session_id)

        # 负责处理传入的消息并生成响应
        response_message = self.forward(*message, session_id=session_id, **kwargs)
        
        # 4. 标准化响应格式
        if not isinstance(response_message, AgentMessage):
            response_message = AgentMessage(sender=self.name, content=response_message)
            
        # 5. 更新记忆
        self.update_memory(response_message, session_id=session_id)
        response_message = copy.deepcopy(response_message)
        
        # 6.执行后置钩子
        for hook in self._hooks.values():
            result = hook.after_agent(self, response_message, session_id)
            if result:
                response_message = result
        return response_message

    def forward(self, *message: AgentMessage, session_id=0, **kwargs) -> Union[AgentMessage, str]:
        """
        消息前向处理
        
        聚合历史消息，调用LLM生成响应
        """
        # 聚合历史消息
        formatted_messages = self.aggregator.aggregate(
            self.memory.get(session_id), self.name, self.output_format, self.template
        )
        # 调用LLM生成响应
        llm_response = self.llm.chat(formatted_messages, **kwargs)
        
        # 格式化响应
        if self.output_format:
            formatted_messages = self.output_format.parse_response(llm_response)
            return AgentMessage(sender=self.name, content=llm_response, formatted=formatted_messages)
        return llm_response

    def __setattr__(self, __name: str, __value: Any) -> None:
        """
        重写对象属性设置方法
        
        @description 当给Agent实例设置属性时的特殊处理方法
        @param {str} __name - 属性名
        @param {Any} __value - 属性值
        @return {None}
        """
        # 检查要设置的值是否为Agent类型的实例
        if isinstance(__value, Agent):
            # 获取_agents属性，如果不存在则创建一个新的OrderedDict
            # getattr的第三个参数OrderedDict()作为默认值，当_agents不存在时返回
            _agents = getattr(self, '_agents', OrderedDict())
            
            # 将新的Agent实例添加到_agents字典中
            # 使用属性名作为键，Agent实例作为值
            _agents[__name] = __value
            
            # 使用父类的__setattr__方法更新_agents字典
            # 这里不直接赋值是为了避免递归调用当前的__setattr__方法
            super().__setattr__('_agents', _agents)
            
        # 对于所有属性(包括Agent实例)，都调用父类的__setattr__方法进行常规的属性设置
        # 这确保了所有属性都能被正确设置，无论是Agent实例还是普通值
        super().__setattr__(__name, __value)

    def state_dict(self, session_id=0):
        """
        获取代理的状态字典
        
        @param {int} session_id - 会话ID，用于标识不同的会话
        @return {dict} - 包含代理及其子代理的记忆状态的字典
        """
        # 初始化状态字典和堆栈，用于深度优先遍历代理及其子代理
        state_dict, stack = {}, [('', self)]
        
        # 遍历堆栈，处理每个代理节点
        while stack:
            # 从堆栈中弹出一个节点
            prefix, node = stack.pop()
            # 构建当前节点的键名
            key = prefix + 'memory'
            
            # 如果节点有记忆，则获取并保存其状态
            if node.memory is not None:
                # 检查会话ID是否存在于记忆映射中
                if session_id not in node.memory.memory_map:
                    warnings.warn(f'No session id {session_id} in {key}')
                # 获取当前会话的记忆
                memory = node.memory.get(session_id)
                # 保存记忆状态到字典中
                state_dict[key] = memory and memory.save() or []
            
            # 如果节点有子代理，则将其加入堆栈
            if hasattr(node, '_agents'):
                for name, value in reversed(node._agents.items()):
                    stack.append((prefix + name + '.', value))
        
        # 返回构建的状态字典
        return state_dict

    def load_state_dict(self, state_dict: Dict, session_id=0):
        """
        加载代理的状态字典
        
        @param {dict} state_dict - 包含代理及其子代理的记忆状态的字典
        @param {int} session_id - 会话ID，用于标识不同的会话
        """
        # 获取当前代理的状态字典
        _state_dict = self.state_dict()
        
        # 检查缺失的键
        missing_keys = set(_state_dict) - set(state_dict)
        if missing_keys:
            raise KeyError(f'Missing keys: {missing_keys}')
        
        # 检查多余的键
        extra_keys = set(state_dict) - set(_state_dict)
        if extra_keys:
            warnings.warn(f'Mismatch keys which are not used: {extra_keys}')
        
        # 遍历状态字典中的每个键
        for key in _state_dict:
            obj = self
            # 解析键路径，逐级获取对象
            for attr in key.split('.')[:-1]:
                if isinstance(obj, AgentList):
                    assert attr.isdigit()
                    obj = obj[int(attr)]
                elif isinstance(obj, AgentDict):
                    obj = obj[attr]
                else:
                    obj = getattr(obj, attr)
            
            # 如果对象有记忆，则加载状态
            if obj.memory is not None:
                # 检查会话ID是否存在于记忆映射中
                if session_id not in obj.memory.memory_map:
                    obj.memory.create_instance(session_id)
                # 加载状态到记忆映射中
                obj.memory.memory_map[session_id].load(state_dict[key] or [])

    def register_hook(self, hook: Callable):
        handle = RemovableHandle(self._hooks)
        self._hooks[handle.id] = hook
        return handle

    def reset(self, session_id=0, keypath: Optional[str] = None, recursive: bool = False):
        """
        重置代理的记忆状态
        
        @param {int} session_id - 会话ID，用于标识不同的会话
        @param {Optional[str]} keypath - 指定子代理的路径
        @param {bool} recursive - 是否递归重置所有子代理
        """
        # 确保keypath和recursive不能同时使用
        assert not (keypath and recursive), 'keypath and recursive can\'t be used together'
        
        if keypath:
            # 如果提供了keypath，解析路径并重置指定的子代理
            keys, agent = keypath.split('.'), self
            for key in keys:
                # 获取当前代理的子代理字典
                agents = getattr(agent, '_agents', {})
                # 检查路径中的key是否存在
                if key not in agents:
                    raise KeyError(f'No sub-agent named {key} in {agent}')
                # 更新当前代理为子代理
                agent = agents[key]
            # 重置指定的子代理
            agent.reset(session_id, recursive=False)
        else:
            # 如果没有提供keypath，重置当前代理的记忆
            if self.memory:
                self.memory.reset(session_id=session_id)
            # 如果递归标志为真，递归重置所有子代理
            if recursive:
                for agent in getattr(self, '_agents', {}).values():
                    agent.reset(session_id, recursive=True)

    def __repr__(self):
        """
        返回代理的字符串表示
        
        @return {str} - 代理的层次结构表示
        """
        def _rcsv_repr(agent, n_indent=1):
            # 构建当前代理的字符串表示
            res = agent.__class__.__name__ + (f"(name='{agent.name}')" if agent.name else '')
            # 递归构建子代理的字符串表示
            modules = [
                f"{n_indent * '  '}({name}): {_rcsv_repr(agent, n_indent + 1)}"
                for name, agent in getattr(agent, '_agents', {}).items()
            ]
            # 如果有子代理，格式化输出
            if modules:
                res += '(\n' + '\n'.join(modules) + f'\n{(n_indent - 1) * "  "})'
            elif not res.endswith(')'):
                res += '()'
            return res

        # 返回代理的层次结构表示
        return _rcsv_repr(self)


class AsyncAgentMixin:
    """
    异步代理混入类
    
    为代理类提供异步消息处理能力
    """

    async def __call__(self, *message: AgentMessage, session_id=0, **kwargs) -> AgentMessage:
        """
        异步调用代理以处理消息
        
        @param {AgentMessage} message - 输入的消息，可以是多个
        @param {int} session_id - 会话ID，用于标识不同的会话
        @param {dict} kwargs - 其他可选参数
        @return {AgentMessage} - 处理后的响应消息
        """
        # 将输入消息标准化为AgentMessage对象
        message = [AgentMessage(sender='user', content=m) if isinstance(m, str) else copy.deepcopy(m) for m in message]
        
        # 执行所有注册的前置钩子函数
        for hook in self._hooks.values():
            result = hook.before_agent(self, message, session_id)
            if result:
                message = result
        
        # 更新记忆存储
        self.update_memory(message, session_id=session_id)
        
        # 异步调用forward方法以生成响应
        response_message = await self.forward(*message, session_id=session_id, **kwargs)
        
        # 如果响应不是AgentMessage类型，则将其包装为AgentMessage
        if not isinstance(response_message, AgentMessage):
            response_message = AgentMessage(sender=self.name, content=response_message)
        
        # 更新记忆存储
        self.update_memory(response_message, session_id=session_id)
        
        # 深拷贝响应消息以避免副作用
        response_message = copy.deepcopy(response_message)
        
        # 执行所有注册的后置钩子函数
        for hook in self._hooks.values():
            result = hook.after_agent(self, response_message, session_id)
            if result:
                response_message = result
        
        # 返回处理后的响应消息
        return response_message

    async def forward(self, *message: AgentMessage, session_id=0, **kwargs) -> Union[AgentMessage, str]:
        """
        异步前向处理消息
        
        @param {AgentMessage} message - 输入的消息，可以是多个
        @param {int} session_id - 会话ID，用于标识不同的会话
        @param {dict} kwargs - 其他可选参数
        @return {Union[AgentMessage, str]} - 生成的响应消息或字符串
        """
        # 聚合历史消息
        formatted_messages = self.aggregator.aggregate(
            self.memory.get(session_id), self.name, self.output_format, self.template
        )
        
        # 异步调用LLM以生成响应
        llm_response = await self.llm.chat(formatted_messages, session_id, **kwargs)
        
        # 如果定义了输出格式化器，则格式化响应
        if self.output_format:
            formatted_messages = self.output_format.parse_response(llm_response)
            return AgentMessage(sender=self.name, content=llm_response, formatted=formatted_messages)
        
        # 返回LLM生成的响应
        return llm_response


class AsyncAgent(AsyncAgentMixin, Agent):
    """Asynchronous variant of the Agent class"""

    pass


class StreamingAgentMixin:
    """
    流式响应代理混入类
    
    为代理添加流式输出能力
    """

    def __call__(self, *message: AgentMessage, session_id=0, **kwargs) -> Generator[AgentMessage, None, None]:
        """
        流式处理消息
        
        逐步生成并返回响应片段
        """
        # 标准化消息格式
        message = [AgentMessage(sender='user', content=m) if isinstance(m, str) else copy.deepcopy(m) for m in message]
        
        # 执行前置钩子
        for hook in self._hooks.values():
            result = hook.before_agent(self, message, session_id)
            if result:
                message = result
                
        # 更新记忆
        self.update_memory(message, session_id=session_id)
        response_message = AgentMessage(sender=self.name, content="")
        
        # 流式生成响应
        for response_message in self.forward(*message, session_id=session_id, **kwargs):
            if not isinstance(response_message, AgentMessage):
                model_state, response = response_message
                response_message = AgentMessage(sender=self.name, content=response, stream_state=model_state)
            yield response_message.model_copy()
            
        # 更新记忆并执行后置钩子
        self.update_memory(response_message, session_id=session_id)
        response_message = copy.deepcopy(response_message)
        for hook in self._hooks.values():
            result = hook.after_agent(self, response_message, session_id)
            if result:
                response_message = result
        yield response_message

    def forward(
        self, *message: AgentMessage, session_id=0, **kwargs
    ) -> Generator[Union[AgentMessage, Tuple[ModelStatusCode, str]], None, None]:
        formatted_messages = self.aggregator.aggregate(
            self.memory.get(session_id), self.name, self.output_format, self.template
        )
        for model_state, response, *_ in self.llm.stream_chat(formatted_messages, session_id=session_id, **kwargs):
            yield (
                AgentMessage(
                    sender=self.name,
                    content=response,
                    formatted=self.output_format.parse_response(response),
                    stream_state=model_state,
                )
                if self.output_format
                else (model_state, response)
            )


class AsyncStreamingAgentMixin:
    """
    异步流式响应代理混入类
    
    为代理添加异步流式输出能力
    """

    async def __call__(self, *message: AgentMessage, session_id=0, **kwargs) -> AsyncGenerator[AgentMessage, None]:
        """
        异步流式处理消息
        
        @param {AgentMessage} message - 输入的消息，可以是多个
        @param {int} session_id - 会话ID，用于标识不同的会话
        @param {dict} kwargs - 其他可选参数
        @return {AsyncGenerator[AgentMessage, None]} - 异步生成的响应消息
        """
        # 实现逻辑与StreamingAgentMixin类似，但使用异步操作
        # 这里省略了具体实现，通常会包含异步处理逻辑

    async def forward(
        self, *message: AgentMessage, session_id=0, **kwargs
    ) -> AsyncGenerator[Union[AgentMessage, Tuple[ModelStatusCode, str]], None]:
        """
        异步前向处理消息
        
        @param {AgentMessage} message - 输入的消息，可以是多个
        @param {int} session_id - 会话ID，用于标识不同的会话
        @param {dict} kwargs - 其他可选参数
        @return {AsyncGenerator[Union[AgentMessage, Tuple[ModelStatusCode, str]], None]} - 异步生成的响应消息或状态码和字符串的元组
        """
        # 聚合历史消息
        formatted_messages = self.aggregator.aggregate(
            self.memory.get(session_id), self.name, self.output_format, self.template
        )
        
        # 异步调用LLM以流式生成响应
        async for model_state, response, *_ in self.llm.stream_chat(
            formatted_messages, session_id=session_id, **kwargs
        ):
            # 如果定义了输出格式化器，则格式化响应
            yield (
                AgentMessage(
                    sender=self.name,
                    content=response,
                    formatted=self.output_format.parse_response(response),
                    stream_state=model_state,
                )
                if self.output_format
                else (model_state, response)
            )


class StreamingAgent(StreamingAgentMixin, Agent):
    """Streaming variant of the Agent class"""

    pass


class AsyncStreamingAgent(AsyncStreamingAgentMixin, Agent):
    """Streaming variant of the AsyncAgent class"""

    pass


class Sequential(Agent):
    """
    Sequential 是一个代理容器类，按添加顺序将消息转发给每个代理。
    """

    def __init__(self, *agents: Union[Agent, Iterable], **kwargs):
        """
        初始化 Sequential 实例
        
        @param {Union[Agent, Iterable]} agents - 一个或多个代理实例或可迭代的代理集合
        @param {dict} kwargs - 其他可选参数
        """
        # 调用父类的初始化方法
        super().__init__(**kwargs)
        # 初始化一个有序字典来存储代理
        self._agents = OrderedDict()
        
        # 确保至少提供一个代理
        if not agents:
            raise ValueError('At least one agent should be provided')
        
        # 如果第一个参数是可迭代对象且不是单个代理实例，则解包
        if isinstance(agents[0], Iterable) and not isinstance(agents[0], Agent):
            if not agents[0]:
                raise ValueError('At least one agent should be provided')
            agents = agents[0]
        
        # 遍历代理集合并添加到有序字典中
        for key, agent in enumerate(agents):
            if isinstance(agents, Mapping):
                key, agent = agent, agents[agent]
            elif isinstance(agent, tuple):
                key, agent = agent
            self.add_agent(key, agent)

    def add_agent(self, name: str, agent: Agent):
        """
        添加代理到有序字典
        
        @param {str} name - 代理的名称
        @param {Agent} agent - 代理实例
        """
        # 确保添加的对象是Agent的子类
        assert isinstance(agent, Agent), f'{type(agent)} is not an Agent subclass'
        # 将代理添加到有序字典中
        self._agents[str(name)] = agent

    def forward(self, *message: AgentMessage, session_id=0, exit_at: Optional[int] = None, **kwargs) -> AgentMessage:
        """
        按顺序将消息转发给每个代理
        
        @param {AgentMessage} message - 输入的消息
        @param {int} session_id - 会话ID
        @param {Optional[int]} exit_at - 指定在某个代理处停止转发
        @param {dict} kwargs - 其他可选参数
        @return {AgentMessage} - 最终处理的消息
        """
        # 确保exit_at参数有效
        assert exit_at is None or exit_at >= 0, 'exit_at should be greater than or equal to 0'
        
        # 如果未指定exit_at，则默认处理到最后一个代理
        if exit_at is None:
            exit_at = len(self) - 1
        
        # 创建一个迭代器，按顺序遍历代理
        iterator = chain.from_iterable(repeat(self._agents.values()))
        
        # 按顺序将消息传递给每个代理，直到exit_at指定的代理
        for _ in range(exit_at + 1):
            agent = next(iterator)
            if isinstance(message, AgentMessage):
                message = (message,)
            message = agent(*message, session_id=session_id, **kwargs)
        
        # 返回最终处理的消息
        return message

    def __getitem__(self, key):
        """
        获取指定索引或键的代理
        
        @param {Union[int, str]} key - 索引或键
        @return {Agent} - 对应的代理实例
        """
        # 支持负索引访问
        if isinstance(key, int) and key < 0:
            assert key >= -len(self), 'index out of range'
            key = len(self) + key
        return self._agents[str(key)]

    def __len__(self):
        """
        返回代理的数量
        
        @return {int} - 代理的数量
        """
        return len(self._agents)


class AsyncSequential(AsyncAgentMixin, Sequential):
    """
    AsyncSequential 是一个异步代理容器类，继承自 AsyncAgentMixin 和 Sequential。
    它按添加顺序异步地将消息转发给每个代理。
    """

    async def forward(
        self, *message: AgentMessage, session_id=0, exit_at: Optional[int] = None, **kwargs
    ) -> AgentMessage:
        """
        异步按顺序将消息转发给每个代理
        
        @param {AgentMessage} message - 输入的消息
        @param {int} session_id - 会话ID
        @param {Optional[int]} exit_at - 指定在某个代理处停止转发
        @param {dict} kwargs - 其他可选参数
        @return {AgentMessage} - 最终处理的消息
        """
        # 确保exit_at参数有效
        assert exit_at is None or exit_at >= 0, 'exit_at should be greater than or equal to 0'
        
        # 如果未指定exit_at，则默认处理到最后一个代理
        if exit_at is None:
            exit_at = len(self) - 1
        
        # 创建一个迭代器，按顺序遍历代理
        iterator = chain.from_iterable(repeat(self._agents.values()))
        
        # 按顺序异步将消息传递给每个代理，直到exit_at指定的代理
        for _ in range(exit_at + 1):
            agent = next(iterator)
            if isinstance(message, AgentMessage):
                message = (message,)
            # 异步调用代理
            message = await agent(*message, session_id=session_id, **kwargs)
        
        # 返回最终处理的消息
        return message


class StreamingSequential(StreamingAgentMixin, Sequential):
    """
    StreamingSequential 是 Sequential 类的流式变体。
    它继承自 StreamingAgentMixin 和 Sequential，提供流式消息处理能力。
    """

    def forward(self, *message: AgentMessage, session_id=0, exit_at: Optional[int] = None, **kwargs):
        """
        流式按顺序将消息转发给每个代理
        
        @param {AgentMessage} message - 输入的消息
        @param {int} session_id - 会话ID
        @param {Optional[int]} exit_at - 指定在某个代理处停止转发
        @param {dict} kwargs - 其他可选参数
        @yield {AgentMessage} - 逐步生成的响应消息
        """
        # 确保exit_at参数有效
        assert exit_at is None or exit_at >= 0, 'exit_at should be greater than or equal to 0'
        
        # 如果未指定exit_at，则默认处理到最后一个代理
        if exit_at is None:
            exit_at = len(self) - 1
        
        # 创建一个迭代器，按顺序遍历代理
        iterator = chain.from_iterable(repeat(self._agents.values()))
        
        # 按顺序将消息传递给每个代理，直到exit_at指定的代理
        for _ in range(exit_at + 1):
            agent = next(iterator)
            if isinstance(message, AgentMessage):
                message = (message,)
            # 流式生成并返回响应消息
            for message in agent(*message, session_id=session_id, **kwargs):
                yield message


class AsyncStreamingSequential(AsyncStreamingAgentMixin, Sequential):
    """
    AsyncStreamingSequential 是 AsyncSequential 类的流式变体。
    它继承自 AsyncStreamingAgentMixin 和 Sequential，提供异步流式消息处理能力。
    """

    async def forward(self, *message: AgentMessage, session_id=0, exit_at: Optional[int] = None, **kwargs):
        """
        异步流式按顺序将消息转发给每个代理
        
        @param {AgentMessage} message - 输入的消息
        @param {int} session_id - 会话ID
        @param {Optional[int]} exit_at - 指定在某个代理处停止转发
        @param {dict} kwargs - 其他可选参数
        @yield {AgentMessage} - 异步生成的响应消息
        """
        # 确保exit_at参数有效
        assert exit_at is None or exit_at >= 0, 'exit_at should be greater than or equal to 0'
        
        # 如果未指定exit_at，则默认处理到最后一个代理
        if exit_at is None:
            exit_at = len(self) - 1
        
        # 创建一个迭代器，按顺序遍历代理
        iterator = chain.from_iterable(repeat(self._agents.values()))
        
        # 按顺序异步将消息传递给每个代理，直到exit_at指定的代理
        for _ in range(exit_at + 1):
            agent = next(iterator)
            if isinstance(message, AgentMessage):
                message = (message,)
            # 异步流式生成并返回响应消息
            async for message in agent(*message, session_id=session_id, **kwargs):
                yield message


class AgentContainerMixin:
    """
    代理容器混入类
    
    提供代理的容器操作功能
    """

    def __init_subclass__(cls):
        """
        子类初始化时包装API方法
        """
        # 调用父类的子类初始化方法
        super().__init_subclass__()

        def wrap_api(func):
            """
            包装API方法，确保正确处理代理实例
            
            @param {Callable} func - 需要包装的函数
            @return {Callable} - 包装后的函数
            """
            @wraps(func)
            def wrapped_func(self, *args, **kwargs):
                # 实现代理容器的操作逻辑
                pass
            return wrapped_func

        # fmt: off
        # 遍历需要包装的方法列表
        for method in [
            'append', 'sort', 'reverse', 'pop', 'clear', 'update',
            'insert', 'extend', 'remove', '__init__', '__setitem__',
            '__delitem__', '__add__', '__iadd__', '__radd__', '__mul__',
            '__imul__', '__rmul__'
        ]:
            # 如果子类中存在该方法，则用wrap_api包装
            if hasattr(cls, method):
                setattr(cls, method, wrap_api(getattr(cls, method)))


class AgentList(Agent, UserList, AgentContainerMixin):
    """
    代理列表类
    
    提供列表形式的代理集合
    """

    def __init__(self, agents: Optional[Iterable[Agent]] = None):
        Agent.__init__(self, memory=None)
        UserList.__init__(self, agents)
        self.name = None


class AgentDict(Agent, UserDict, AgentContainerMixin):
    """
    代理字典类
    
    提供字典形式的代理集合
    """

    def __init__(self, agents: Optional[Mapping[str, Agent]] = None):
        Agent.__init__(self, memory=None)
        UserDict.__init__(self, agents)
        self.name = None
